<?php
/**
 * Description
 * 
 * PHP version 7
 * 
 * @category Custom
 * @package  Custom
 * @author   ryu <mo5467@126.com>
 * @date     2020-04-30 00:08:51
 * @lastTime 2020-05-02 00:30:33
 * @license  https://opensource.org/licenses/MIT MIT License
 * @link     none
 */
namespace Test\Unit;

use Design\Other\Repository\Post;
use Design\Other\Repository\PostId;
use Design\Other\Repository\PostStatus;
use Design\Other\Repository\PostRepository;
use Design\Other\Repository\InMemoryPersistence;

class PersistenceTest extends \Test\BaseTest
{
    private $repository;

    public function setUp() : void
    {
        $this->repository = new PostRepository(new InMemoryPersistence());
    }

    public function testCanGenerateId()
    {
        $this->assertSame(1, $this->repository->generateId()->toInt());
    }

    public function testThrowsExceptionWhenTryingToFindPostWhichDoesNotExist()
    {
        $this->expectException(\OutOfBoundsException::class);
        $this->expectExceptionMessage('Post with id 42 not found');

        $this->repository->findById(PostId::fromInt(42));

    }

    public function testThrowExceptionWhenGiveWrongRange()
    {
        $this->expectException(\InvalidArgumentException::class);
        PostId::fromInt(-1);
    }

    public function testThrowsExceptionWhenTryingToFindPostStatusWhichDoesNotExist()
    {
        $this->expectException(\InvalidArgumentException::class);

        PostStatus::fromString('invalid');

    }

    public function testThrowExceptionWhenGiveStatusWrongRange()
    {
        $this->expectException(\InvalidArgumentException::class);
        PostStatus::fromInt(0);
    }

    public function testCanPersistPostDraft()
    {
        $postId = $this->repository->generateId();
        $post = Post::draft($postId, 'Repository Pattern', 'Design Patterns PHP');
        $this->repository->save($post);

        $this->repository->findById($postId);

        $this->assertEquals($postId, $this->repository->findById($postId)->getId());
        $this->assertSame(PostStatus::STATE_DRAFT, $post->getStatus()->toString());

        $this->expectException(\OutOfBoundsException::class);
        $this->expectExceptionMessage('Post with id 1 not found');

        $this->repository->remove($post);
        $this->repository->findById($postId);

    }

    public function testCanInstanceStatusFromInteger()
    {
        $status = PostStatus::fromInt(1);
        $this->assertSame(1, $status->toInt());
        $this->assertSame(PostStatus::STATE_DRAFT, $status->toString());
    }

    public function testThrowsExceptionWhenTryingToRemovePostWhichDoesNotExist()
    {
        $this->expectException(\OutOfBoundsException::class);
        $this->expectExceptionMessage('No data found for id 1');
        $postId = $this->repository->generateId();
        $post = Post::draft($postId, 'Repository Pattern', 'Design Patterns PHP');
        $this->repository->remove($post);

    }
}